import { lstatSync, readFileSync } from 'fs';
// import { join } from 'path';
import validate from 'validate-npm-package-name';

export function convertPathSeparator(path: string, replace = '-'): string {
  const regex = /[/\\]/g;
  if (regex.test(path)) {
    return path
      .replace(/(^[/\\]+|[/\\]+$)/g, '')
      .replace(/[/\\]{2,}/g, '/')
      .replace(regex, replace);
  }
  return path;
}

export function isDir(path: string): boolean {
  try {
    return lstatSync(path).isDirectory();
  } catch (e) {
    return false;
  }
}

export function isFile(path: string): boolean {
  try {
    return lstatSync(path).isFile();
  } catch (e) {
    return false;
  }
}

// eslint-disable-next-line @typescript-eslint/ban-types
export function loadJsonObjectThrow<T = {}>(path: string): T {
  const buf = readFileSync(path);
  if (buf != null) {
    const obj = JSON.parse(buf.toString());
    if (obj != null && typeof obj === 'object' && !Array.isArray(obj)) {
      return obj as T;
    }
    throw new Error('JSON data is not an object!');
  }
  throw new Error('JSON data wrong!');
}

// eslint-disable-next-line @typescript-eslint/ban-types
export function loadJsonObject<T = {}>(path: string, dft?: T): T | undefined {
  try {
    const buf = readFileSync(path);
    if (buf != null) {
      const obj = JSON.parse(buf.toString());
      if (obj != null && typeof obj === 'object' && !Array.isArray(obj)) {
        return obj as T;
      }
    }
    return dft ?? undefined;
  } catch (e) {
    return dft ?? undefined;
  }
}

export function filterWorkingDir(dir?: string | null): string | undefined {
  if (dir == null || dir.trim() === '') return undefined;
  return dir.trim();
}

export function validateProjectName(name: string) {
  const { validForNewPackages, validForOldPackages, errors, warnings } = validate(name);

  if (!validForNewPackages && !validForOldPackages) {
    throw new Error(`Invalid project name about "${name}", ${errors != null ? errors.join('\n') : '!'}`);
  }

  if (warnings != null) {
    console.warn(warnings);
  }
}

// export type CloudBaseShortenRegion = 'gz' | 'bj' | 'sh' | 'nj' | 'cd' | 'cq';
//
// export type CloudBaseRegion =
//   | 'ap-guangzhou'
//   | 'ap-beijing'
//   | 'ap-shanghai'
//   | 'ap-nanjing'
//   | 'ap-chengdu'
//   | 'ap-chongqing';

export function choicesCloudBaseShortenRegions(): string[] {
  return ['gz', 'bj', 'sh', 'nj', 'cd', 'cq'];
}

export function choicesCloudBaseRegions(): string[] {
  return ['ap-guangzhou', 'ap-beijing', 'ap-shanghai', 'ap-nanjing', 'ap-chengdu', 'ap-chongqing'];
}

export function choicesRegions(): string[] {
  return choicesCloudBaseRegions().concat(choicesCloudBaseShortenRegions());
}

let regions: Record<string, string>;

export function getRegionsMap(): Record<string, string> {
  if (regions == null) {
    regions = {};
    const shorten = choicesCloudBaseShortenRegions();
    choicesCloudBaseRegions().forEach((region, idx) => {
      regions[region] = region;
      regions[region.replace(/^ap-/, '')] = region;
      if (shorten[idx] != null) {
        regions[shorten[idx]] = region;
      }
    });
  }
  return regions;
}

export function filterCloudBaseRegion(region?: string): string | undefined {
  if (region == null) return undefined;
  const map = getRegionsMap();
  return map[region] ?? undefined;
}
